﻿using Mapster;
using Raffles.OA.Data;
using Raffles.OA.Service;
using Raffles.OA.Utility;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Raffles.OA.WebApp.Areas.Finance.Controllers
{
    /// <summary>
    /// 财务模块-已结算项目管理
    /// </summary>
    public class ProjectController : BaseController<ProjectEntity>
    {
        private UserService _userService;

        public ProjectController()
        {
            _userService = new UserService();
        }

        #region 视图

        /// <summary>
        /// 项目回款表单
        /// </summary>
        /// <returns></returns>
        public ActionResult ReturnPaymentForm()
        {
            return View();
        }

        /// <summary>
        /// 项目回款明细
        /// </summary>
        /// <returns></returns>
        public ActionResult ReturnPaymentView()
        {
            return View();
        }

        /// <summary>
        /// 看板
        /// </summary>
        /// <returns></returns>
        public ActionResult DashBoard()
        {
            return View();
        }

        /// <summary>
        /// 运营成本
        /// </summary>
        /// <returns></returns>
        public ActionResult OperateCostForm()
        {
            return View();
        }

        /// <summary>
        /// 运营成本
        /// </summary>
        /// <returns></returns>
        public ActionResult OperateCostView()
        {
            return View();
        }

        /// <summary>
        /// 项目提成
        /// </summary>
        /// <returns></returns>
        public ActionResult ProjectCommision()
        {
            return View();
        }

        /// <summary>
        /// 销售提成
        /// </summary>
        /// <returns></returns>
        public ActionResult SaleReport()
        {
            return View();
        }

        /// <summary>
        /// 销售操作率
        /// </summary>
        /// <returns></returns>
        public ActionResult OperateRateForm()
        {
            return View();
        }

        /// <summary>
        /// 付款申请
        /// </summary>
        /// <returns></returns>
        public ActionResult PayApply()
        {
            return View();
        }


        #endregion 视图

        /// <summary>
        /// 财务项目列表(>=等待收支)
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetPageListJson(ProjectSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            List<OrderByModel> orderList = OrderByModel.Create(
            new OrderByModel() { FieldName = pagination.Sort, OrderByType = pagination.SortType.ToUpper() == "ASC" ? OrderByType.Asc : OrderByType.Desc }
            );
            var datas = await _dbContext.Queryable<ProjectEntity>()
                                .Includes(x => x.ProjectPayments)
                                .Includes(x => x.ProjectReturnPayments)
                                .Includes(x => x.ProjectOperateCosts)
                                .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && (x.Status == (int)ProjectStatusEnum.WaitMoney || x.Status == (int)ProjectStatusEnum.Done || x.Status == (int)ProjectStatusEnum.Closed))
                                .WhereIF(!param.KeyWord.IsEmpty(), x => x.Code.Contains(param.KeyWord) || x.ContractCode.Contains(param.KeyWord) || x.Name.Contains(param.KeyWord) || x.CustomerName.Contains(param.KeyWord))
                                .WhereIF(!param.Status.IsEmpty(), x => x.Status == param.Status)
                                .WhereIF(!param.DepartureDateStart.IsEmpty(), x => x.DepartureDate >= param.DepartureDateStart && x.DepartureDate <= param.DepartureDateEnd)
                                .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                .OrderBy(orderList)
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);
            datas.ForEach(x =>
            {
                x.TotalReturnPaymentAmount = x.ProjectPayments.Where(y => y.ProjectId == x.Id && y.PaymentType == PaymentTypeEnum.AdvancePay.ToString()).Sum(y => y.AmountRMB * x.PaymentRate) + x.ProjectReturnPayments.Where(z => z.ProjectId == x.Id).Sum(z => z.Rate * z.PayAmount);
                x.TotalOperateCostAmount = x.ProjectOperateCosts.Where(y => y.ProjectId == x.Id).Sum(y => y.Amount);
            });
            return Content(DataResult<List<ProjectEntity>>.PageResult(datas, totalCount).ToJson());
        }

        /// <summary>
        /// 获取成本结算单列表
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetPageDetailListJson(int projectId)
        {
            List<ProjectEntity> datas = await _dbContext.Queryable<ProjectEntity>()
                                                        .Where(x => x.ParentId == projectId)
                                                        .OrderBy(x => x.DepartureDate)
                                                        .ToListAsync();
            return Content(DataResult<List<ProjectEntity>>.Success(datas).ToJson());
        }

        /// <summary>
        /// 项目完成(财务)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> CompleteProject(string ids)
        {
            try
            {
                int[] idsArr = ids.SpitIntArrary();
                await _dbContext.Updateable<ProjectEntity>().SetColumns(x =>
                new ProjectEntity()
                {
                    Status = (int)ProjectStatusEnum.Done,
                    UpdatedOn = DateTime.Now,
                    UpdatedBy = OperatorProvider.Provider.GetCurrent().Id
                })
                 .Where(x => idsArr.Contains(x.Id) || idsArr.Contains(Convert.ToInt32(x.ParentId))).ExecuteCommandAsync();
                return Json(DataResult.Success("项目完成！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 项目退回(财务操作-至销售)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> BackProjectSale(int projectId)
        {
            try
            {
                await _dbContext.Updateable<ProjectEntity>().SetColumns(x =>
                new ProjectEntity()
                {
                    Status = (int)ProjectStatusEnum.DataIn,
                    UpdatedOn = DateTime.Now,
                    UpdatedBy = OperatorProvider.Provider.GetCurrent().Id
                })
                .Where(x => x.Id == projectId || x.ParentId == projectId).ExecuteCommandAsync(); 
                return Json(DataResult.Success("项目退回！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 项目退回(管理操作至财务)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> BackProjectFinance(int projectId)
        {
            try
            {
                await _dbContext.Updateable<ProjectEntity>().SetColumns(x =>
                new ProjectEntity()
                {
                    Status = (int)ProjectStatusEnum.WaitMoney,
                    UpdatedOn = DateTime.Now,
                    UpdatedBy = OperatorProvider.Provider.GetCurrent().Id
                })
                .Where(x => x.Id == projectId || x.ParentId == projectId).ExecuteCommandAsync(); 
                return Json(DataResult.Success("项目退回！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 获取项目回款表单默认数据
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<ActionResult> SetReturnPayFormJson(int projectId)
        {
            try
            {
                ReturnPayDto returnPayDto = new ReturnPayDto();
                ProjectEntity projectEntity = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(projectId);
                returnPayDto.ProjectId = projectId;
                //默认结算单中的货币
                returnPayDto.Currency = projectEntity.SettlementCurrency;
                //默认结算单中的付款汇率
                returnPayDto.Rate = projectEntity.PaymentRate;
                //人民币销售金额-含税
                returnPayDto.SaleRMBAmountAfterTax = projectEntity.SaleRMBAmountAfterTax;
                //人民币已付金额(历史回款+定金)-含税
                decimal returnAmounts = await _dbContext.Queryable<ProjectReturnPaymentEntity>().Where(x => x.ProjectId == projectId).SumAsync(x => x.PayAmount * x.Rate) ?? 0;
                decimal? advanceAmounts = (await _dbContext.Queryable<ProjectPaymentEntity>().Where(x => x.ProjectId == projectId && x.PaymentType == PaymentTypeEnum.AdvancePay.ToString()).FirstAsync())?.AmountRMB;//定金目前都是按税前来保存的
                returnPayDto.PaidRMBAmountAfterTax = returnAmounts + advanceAmounts ?? 0 * projectEntity.TaxRate;
                //人民币未付金额(销售金额-已付金额)-含税
                returnPayDto.NoPayRMBAmountAfterTax = returnPayDto.SaleRMBAmountAfterTax - returnPayDto.PaidRMBAmountAfterTax;
                return Content(DataResult<ReturnPayDto>.Success(returnPayDto).ToJson());
            }
            catch (Exception ex)
            {
                return Content(DataResult.Error($"数据获取失败,{ex.Message}").ToJson());
            }
        }

        /// <summary>
        /// 保存项目回款表单
        /// </summary>
        /// <param name="returnPayDto"></param>
        /// <returns></returns>

        [HttpPost]
        public async Task<ActionResult> SaveReturnPayFormJson(ReturnPayDto returnPayDto)
        {
            try
            {
                ProjectReturnPaymentEntity entity = null;
                if (returnPayDto.Id == null)
                {
                    entity = new ProjectReturnPaymentEntity();
                    returnPayDto.Adapt(entity);
                    entity.CreatedBy = entity.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    entity.UpdatedOn = entity.CreatedOn;
                    await _dbContext.Insertable<ProjectReturnPaymentEntity>(entity).ExecuteCommandAsync();
                }
                else
                {
                    entity = await _dbContext.Queryable<ProjectReturnPaymentEntity>().InSingleAsync(returnPayDto.Id);
                    returnPayDto.Adapt(entity);
                    entity.UpdatedOn = DateTime.Now;
                    entity.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    await _dbContext.Updateable<ProjectReturnPaymentEntity>(entity).ExecuteCommandAsync();
                }
                return Json(DataResult.Success());
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"{ex.Message}"));
            }
        }

        /// <summary>
        /// 获取财务回款明细
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> GetReturnPayDetailJson(int projectId)
        {
            List<ReturnPayDto> datas = await _dbContext.Queryable<ProjectReturnPaymentEntity>()
                                                       .Where(x => x.ProjectId == projectId)
                                                       .OrderBy(x => x.PayAmountOn)
                                                       .Select(x => new ReturnPayDto
                                                       {
                                                           Id = x.Id,
                                                           Currency = x.Currency,
                                                           Rate = x.Rate,
                                                           PayAmount = x.PayAmount,
                                                           PayAmountOn = x.PayAmountOn,
                                                           Remark = x.Remark,
                                                           UpdatedOn = x.UpdatedOn
                                                       })
                                                       .ToListAsync();
            ProjectEntity entity = await _dbContext.Queryable<ProjectEntity>().Includes(x => x.ProjectPayments).InSingleAsync(projectId);
            var advanceRMBAmount = entity.ProjectPayments.FirstOrDefault(x => x.PaymentType == PaymentTypeEnum.AdvancePay.ToString())?.AmountRMB ?? 0;
            if (advanceRMBAmount > 0)
            {
                datas.Insert(0, new ReturnPayDto
                {
                    Currency = entity.SettlementCurrency,
                    Rate = entity.PaymentRate,
                    PayAmount = advanceRMBAmount,
                    Remark = "定金"
                });
            }
            return Content(DataResult<List<ReturnPayDto>>.Success(datas).ToJson());
        }

        /// <summary>
        /// 删除回款记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> DeleteReturnPayment(int returnPayId)
        {
            await _dbContext.Deleteable<ProjectReturnPaymentEntity>().In(returnPayId).ExecuteCommandAsync();
            return Json(DataResult.Success("删除成功！"));
        }

        /// <summary>
        /// 获取运营成本
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> GetOperateCostJson(int projectId)
        {
            var data = await _dbContext.Queryable<ProjectEntity>().Includes(x => x.ProjectOperateCosts).InSingleAsync(projectId);
            ProjectOperateCostVo projectOperateCostVo = new ProjectOperateCostVo()
            {
                SaleRMBAmountAfterTax = data.SaleRMBAmountAfterTax,
                Profit = data.SaleRMBAmountAfterTax - data.CostRMBAmountAfterTax,
                ProjectOperateCosts = data.ProjectOperateCosts
            };
            return Content(DataResult<ProjectOperateCostVo>.Success(projectOperateCostVo).ToJson());
        }

        /// <summary>
        /// 获取运营成本
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> GetOperateCostListJson(int projectId)
        {
            var datas = await _dbContext.Queryable<ProjectOperateCostEntity>().Where(x => x.ProjectId == projectId).ToListAsync();
            return Content(DataResult<List<ProjectOperateCostEntity>>.Success(datas).ToJson());
        }

        /// <summary>
        /// 保存运营成本
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> SaveOperateCostJson(OperateCost operateCost)
        {
            try
            {
                await _dbContext.BeginTranAsync();
                //清空原有
                await _dbContext.Deleteable<ProjectOperateCostEntity>().Where(x => x.ProjectId == operateCost.ProjectId).ExecuteCommandAsync();
                //保存列表
                List<ProjectOperateCostEntity> entities = operateCost.OperateCostItems.Select(x => new ProjectOperateCostEntity
                {
                    ProjectId = operateCost.ProjectId,
                    Code = x.Code,
                    Name = x.Name,
                    Rate = x.Rate,
                    Amount = x.Amount,
                    IsDefault = x.IsDefault
                }).ToList();
                await _dbContext.Insertable<ProjectOperateCostEntity>(entities).ExecuteCommandAsync();

                await _dbContext.CommitTranAsync();

                return Json(DataResult.Success("保存成功！"));
            }
            catch (Exception ex)
            {
                await _dbContext.RollbackTranAsync();
                return Json(DataResult.Error($"{ex.Message}"));
            }
        }

        /// <summary>
        /// 项目提成(>=项目完成)
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetCommisionPageListJson(ProjectSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            List<OrderByModel> orderList = OrderByModel.Create(
            new OrderByModel() { FieldName = pagination.Sort, OrderByType = pagination.SortType.ToUpper() == "ASC" ? OrderByType.Asc : OrderByType.Desc }
            );
            var datas = await _dbContext.Queryable<ProjectEntity>()
                                .Includes(x => x.ProjectOperateCosts)
                                .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && (x.Status == (int)ProjectStatusEnum.Done || x.Status == (int)ProjectStatusEnum.Closed))
                                .WhereIF(!param.KeyWord.IsEmpty(), x => x.Code.Contains(param.KeyWord) || x.ContractCode.Contains(param.KeyWord) || x.Name.Contains(param.KeyWord) || x.CustomerName.Contains(param.KeyWord))
                                .WhereIF(!param.DepartureDateStart.IsEmpty(), x => x.DepartureDate >= param.DepartureDateStart && x.DepartureDate <= param.DepartureDateEnd)
                                .WhereIF(!param.Status.IsEmpty(), x => x.Status == param.Status)
                                .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                .OrderBy(orderList)
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);
            datas.ForEach(x =>
            {
                //运营成本
                x.TotalOperateCostAmount = x.ProjectOperateCosts.Where(y => y.ProjectId == x.Id).Sum(y => y.Amount);
                //销售提成([税后销售额-税后成本-运营成本]*操作率)
                if (x.OperateRate <= 1)
                {
                    x.SalerCommissionAmount = (x.SaleRMBAmountAfterTax - x.CostRMBAmountAfterTax - x.TotalOperateCostAmount) * x.OperateRate;
                }
                else
                {
                    x.SalerCommissionAmount = x.OperateRate;
                }
            });
            return Content(DataResult<List<ProjectEntity>>.PageResult(datas, totalCount).ToJson());
        }

        /// <summary>
        /// 项目关闭
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> CloseProject(string ids)
        {
            try
            {
                int[] idsArr = ids.SpitIntArrary();
                await _dbContext.Updateable<ProjectEntity>().SetColumns(x =>
                new ProjectEntity()
                {
                    Status = (int)ProjectStatusEnum.Closed,
                    UpdatedOn = DateTime.Now,
                    UpdatedBy = OperatorProvider.Provider.GetCurrent().Id
                })
                 .Where(x => idsArr.Contains(x.Id) || idsArr.Contains(Convert.ToInt32(x.ParentId))).ExecuteCommandAsync();
                return Json(DataResult.Success("项目关闭！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 操作销售提成
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetSalerCommisionPageListJson(SaleReportSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
            List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                .Includes(x => x.ProjectOperateCosts)
                                .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);

            queryable = queryable.Select(x => new ProjectEntity
            {
                DepartureDate = x.DepartureDate,
                SaleManagerId = x.SaleManagerId,
                //销售提成([税后销售额-税后成本-运营成本]*操作率)
                SalerCommissionAmount = x.OperateRate <= 1 ? (x.SaleRMBAmountAfterTax - x.CostRMBAmountAfterTax - x.ProjectOperateCosts.Where(y => y.ProjectId == x.Id).Sum(y => y.Amount)) * x.OperateRate : x.OperateRate
            }).ToList();
            var groupbyResult = queryable.GroupBy(x => new
            {
                Month = x.DepartureDate.Value.ToString("yyyy-MM"),
                SaleManagerId = x.SaleManagerId
            })
            .Select(x => new
            {
                SaleManagerId = x.Key.SaleManagerId,
                Month = x.Key.Month,
                Amount = x.Sum(y => y.SalerCommissionAmount)//汇总销售提成
            }).ToList();
            //所有销售
            var salers = await _userService.GetSalerList(param.SalerId);
            List<SaleReportVo> monthDatas = new List<SaleReportVo>();
            foreach (var item in salers)
            {
                //如果当前销售员没有销售数据
                if (!groupbyResult.Any(x => x.SaleManagerId == item.Id))
                {
                    monthDatas.Add(new SaleReportVo
                    {
                        SaleId = item.Id,
                        SaleName = item.RealName
                    });
                }
                else
                {
                    SaleReportVo saleCommosionVo = new SaleReportVo
                    {
                        SaleId = item.Id,
                        SaleName = item.RealName
                    };
                    for (int i = 1; i <= 12; i++)
                    {
                        var data = Math.Round((groupbyResult.FirstOrDefault(x => x.SaleManagerId == item.Id && x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                        switch (i)
                        {
                            case 1:
                                saleCommosionVo.January = data;
                                break;

                            case 2:
                                saleCommosionVo.February = data;
                                break;

                            case 3:
                                saleCommosionVo.March = data;
                                break;

                            case 4:
                                saleCommosionVo.April = data;
                                break;

                            case 5:
                                saleCommosionVo.May = data;
                                break;

                            case 6:
                                saleCommosionVo.June = data;
                                break;

                            case 7:
                                saleCommosionVo.July = data;
                                break;

                            case 8:
                                saleCommosionVo.August = data;
                                break;

                            case 9:
                                saleCommosionVo.September = data;
                                break;

                            case 10:
                                saleCommosionVo.October = data;
                                break;

                            case 11:
                                saleCommosionVo.November = data;
                                break;

                            case 12:
                                saleCommosionVo.December = data;
                                break;
                        }
                        saleCommosionVo.Total = saleCommosionVo.Total + data;
                    }
                    monthDatas.Add(saleCommosionVo);
                }
            }
            return Content(DataResult<List<SaleReportVo>>.PageResult(monthDatas, totalCount).ToJson());
        }

        /// <summary>
        /// 操作销售提成导出
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> ExportSalerCommisionJson(SaleReportSearchParam param)
        {
            try
            {
                param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
                List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                    .Includes(x => x.ProjectOperateCosts)
                                    .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                    .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                    .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                    .ToListAsync();

                queryable = queryable.Select(x => new ProjectEntity
                {
                    DepartureDate = x.DepartureDate,
                    SaleManagerId = x.SaleManagerId,
                    //销售提成([税后销售额-税后成本-运营成本]*操作率)
                    SalerCommissionAmount = x.OperateRate <= 1 ? (x.SaleRMBAmountAfterTax - x.CostRMBAmountAfterTax - x.ProjectOperateCosts.Where(y => y.ProjectId == x.Id).Sum(y => y.Amount)) * x.OperateRate : x.OperateRate
                }).ToList();
                var groupbyResult = queryable.GroupBy(x => new
                {
                    Month = x.DepartureDate.Value.ToString("yyyy-MM"),
                    SaleManagerId = x.SaleManagerId
                })
                .Select(x => new
                {
                    SaleManagerId = x.Key.SaleManagerId,
                    Month = x.Key.Month,
                    Amount = x.Sum(y => y.SalerCommissionAmount)//汇总销售提成
                }).ToList();
                //所有销售
                var salers = await _userService.GetSalerList(param.SalerId);
                List<SaleReportVo> monthDatas = new List<SaleReportVo>();
                foreach (var item in salers)
                {
                    //如果当前销售员没有销售数据
                    if (!groupbyResult.Any(x => x.SaleManagerId == item.Id))
                    {
                        monthDatas.Add(new SaleReportVo
                        {
                            SaleId = item.Id,
                            SaleName = item.RealName
                        });
                    }
                    else
                    {
                        SaleReportVo saleCommosionVo = new SaleReportVo
                        {
                            SaleId = item.Id,
                            SaleName = item.RealName
                        };
                        for (int i = 1; i <= 12; i++)
                        {
                            var data = Math.Round((groupbyResult.FirstOrDefault(x => x.SaleManagerId == item.Id && x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                            switch (i)
                            {
                                case 1:
                                    saleCommosionVo.January = data;
                                    break;

                                case 2:
                                    saleCommosionVo.February = data;
                                    break;

                                case 3:
                                    saleCommosionVo.March = data;
                                    break;

                                case 4:
                                    saleCommosionVo.April = data;
                                    break;

                                case 5:
                                    saleCommosionVo.May = data;
                                    break;

                                case 6:
                                    saleCommosionVo.June = data;
                                    break;

                                case 7:
                                    saleCommosionVo.July = data;
                                    break;

                                case 8:
                                    saleCommosionVo.August = data;
                                    break;

                                case 9:
                                    saleCommosionVo.September = data;
                                    break;

                                case 10:
                                    saleCommosionVo.October = data;
                                    break;

                                case 11:
                                    saleCommosionVo.November = data;
                                    break;

                                case 12:
                                    saleCommosionVo.December = data;
                                    break;
                            }
                            saleCommosionVo.Total = saleCommosionVo.Total + data;
                        }
                        monthDatas.Add(saleCommosionVo);
                    }
                }
                if (monthDatas.Count() == 0)
                {
                    return Content(DataResult<int>.Warn(0, "暂无数据导出").ToJson());
                }
                //导出列名
                string[] column = new string[] { "SaleName", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
                //文件名
                var fileName = "操作销售提成.xls";
                //表头
                var headerText = "操作销售提成";
                var file = ExcelHelper<SaleReportVo>.ExportToExcel(fileName, headerText, monthDatas, column);
                return Content(DataResult<string>.Success(file, "导出成功").ToJson());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 操作销售金额
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetSalerAmountPageListJson(SaleReportSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
            List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                .Includes(x => x.ProjectOperateCosts)
                                .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);


            var groupbyResult = queryable.GroupBy(x => new
            {
                Month = x.DepartureDate.Value.ToString("yyyy-MM"),
                SaleManagerId = x.SaleManagerId
            })
            .Select(x => new
            {
                SaleManagerId = x.Key.SaleManagerId,
                Month = x.Key.Month,
                Amount = x.Sum(y => y.SaleRMBAmountAfterTax)//汇总销售金额
            }).ToList();
            //所有销售
            var salers = await _userService.GetSalerList(param.SalerId);
            List<SaleReportVo> monthDatas = new List<SaleReportVo>();
            foreach (var item in salers)
            {
                //如果当前销售员没有销售数据
                if (!groupbyResult.Any(x => x.SaleManagerId == item.Id))
                {
                    monthDatas.Add(new SaleReportVo
                    {
                        SaleId = item.Id,
                        SaleName = item.RealName
                    });
                }
                else
                {
                    SaleReportVo saleCommosionVo = new SaleReportVo
                    {
                        SaleId = item.Id,
                        SaleName = item.RealName
                    };
                    for (int i = 1; i <= 12; i++)
                    {
                        var data = Math.Round((groupbyResult.FirstOrDefault(x => x.SaleManagerId == item.Id && x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                        switch (i)
                        {
                            case 1:
                                saleCommosionVo.January = data;
                                break;

                            case 2:
                                saleCommosionVo.February = data;
                                break;

                            case 3:
                                saleCommosionVo.March = data;
                                break;

                            case 4:
                                saleCommosionVo.April = data;
                                break;

                            case 5:
                                saleCommosionVo.May = data;
                                break;

                            case 6:
                                saleCommosionVo.June = data;
                                break;

                            case 7:
                                saleCommosionVo.July = data;
                                break;

                            case 8:
                                saleCommosionVo.August = data;
                                break;

                            case 9:
                                saleCommosionVo.September = data;
                                break;

                            case 10:
                                saleCommosionVo.October = data;
                                break;

                            case 11:
                                saleCommosionVo.November = data;
                                break;

                            case 12:
                                saleCommosionVo.December = data;
                                break;
                        }
                        saleCommosionVo.Total = saleCommosionVo.Total + data;
                    }
                    monthDatas.Add(saleCommosionVo);
                }
            }
            return Content(DataResult<List<SaleReportVo>>.PageResult(monthDatas, totalCount).ToJson());
        }

        /// <summary>
        /// 操作销售金额导出
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> ExportSalerAmountJson(SaleReportSearchParam param)
        {
            try
            {
                param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
                List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                    .Includes(x => x.ProjectOperateCosts)
                                    .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                    .WhereIF(!param.SalerId.IsEmpty(), x => x.SaleManagerId == param.SalerId)
                                    .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                    .ToListAsync();
                var groupbyResult = queryable.GroupBy(x => new
                {
                    Month = x.DepartureDate.Value.ToString("yyyy-MM"),
                    SaleManagerId = x.SaleManagerId
                })
                .Select(x => new
                {
                    SaleManagerId = x.Key.SaleManagerId,
                    Month = x.Key.Month,
                    Amount = x.Sum(y => y.SaleRMBAmountAfterTax)//汇总销售金额
                }).ToList();
                //所有销售
                var salers = await _userService.GetSalerList(param.SalerId);
                List<SaleReportVo> monthDatas = new List<SaleReportVo>();
                foreach (var item in salers)
                {
                    //如果当前销售员没有销售数据
                    if (!groupbyResult.Any(x => x.SaleManagerId == item.Id))
                    {
                        monthDatas.Add(new SaleReportVo
                        {
                            SaleId = item.Id,
                            SaleName = item.RealName
                        });
                    }
                    else
                    {
                        SaleReportVo saleCommosionVo = new SaleReportVo
                        {
                            SaleId = item.Id,
                            SaleName = item.RealName
                        };
                        for (int i = 1; i <= 12; i++)
                        {
                            var data = Math.Round((groupbyResult.FirstOrDefault(x => x.SaleManagerId == item.Id && x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                            switch (i)
                            {
                                case 1:
                                    saleCommosionVo.January = data;
                                    break;

                                case 2:
                                    saleCommosionVo.February = data;
                                    break;

                                case 3:
                                    saleCommosionVo.March = data;
                                    break;

                                case 4:
                                    saleCommosionVo.April = data;
                                    break;

                                case 5:
                                    saleCommosionVo.May = data;
                                    break;

                                case 6:
                                    saleCommosionVo.June = data;
                                    break;

                                case 7:
                                    saleCommosionVo.July = data;
                                    break;

                                case 8:
                                    saleCommosionVo.August = data;
                                    break;

                                case 9:
                                    saleCommosionVo.September = data;
                                    break;

                                case 10:
                                    saleCommosionVo.October = data;
                                    break;

                                case 11:
                                    saleCommosionVo.November = data;
                                    break;

                                case 12:
                                    saleCommosionVo.December = data;
                                    break;
                            }
                            saleCommosionVo.Total = saleCommosionVo.Total + data;
                        }
                        monthDatas.Add(saleCommosionVo);
                    }
                }
                if (monthDatas.Count() == 0)
                {
                    return Content(DataResult<int>.Warn(0, "暂无数据导出").ToJson());
                }
                //导出列名
                string[] column = new string[] { "SaleName", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
                //文件名
                var fileName = "操作销售金额.xls";
                //表头
                var headerText = "操作销售金额";
                var file = ExcelHelper<SaleReportVo>.ExportToExcel(fileName, headerText, monthDatas, column);
                return Content(DataResult<string>.Success(file, "导出成功").ToJson());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 团队销售金额
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetSalerGroupAmountPageListJson(SaleReportSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
            List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                .Includes(x => x.ProjectOperateCosts)
                                .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);


            var groupbyResult = queryable.GroupBy(x => new
            {
                Month = x.DepartureDate.Value.ToString("yyyy-MM")
            })
            .Select(x => new
            {
                Month = x.Key.Month,
                Amount = x.Sum(y => y.SaleRMBAmountAfterTax)//汇总销售金额
            }).ToList();
            List<SaleReportVo> monthDatas = new List<SaleReportVo>();
            SaleReportVo saleCommosionVo = new SaleReportVo();
            for (int i = 1; i <= 12; i++)
            {
                var data = Math.Round((groupbyResult.FirstOrDefault(x => x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                switch (i)
                {
                    case 1:
                        saleCommosionVo.January = data;
                        break;

                    case 2:
                        saleCommosionVo.February = data;
                        break;

                    case 3:
                        saleCommosionVo.March = data;
                        break;

                    case 4:
                        saleCommosionVo.April = data;
                        break;

                    case 5:
                        saleCommosionVo.May = data;
                        break;

                    case 6:
                        saleCommosionVo.June = data;
                        break;

                    case 7:
                        saleCommosionVo.July = data;
                        break;

                    case 8:
                        saleCommosionVo.August = data;
                        break;

                    case 9:
                        saleCommosionVo.September = data;
                        break;

                    case 10:
                        saleCommosionVo.October = data;
                        break;

                    case 11:
                        saleCommosionVo.November = data;
                        break;

                    case 12:
                        saleCommosionVo.December = data;
                        break;
                }
                saleCommosionVo.Total = saleCommosionVo.Total + data;
            }
            monthDatas.Add(saleCommosionVo);
            return Content(DataResult<List<SaleReportVo>>.PageResult(monthDatas, totalCount).ToJson());
        }

        /// <summary>
        /// 团队销售金额导出
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> ExportSalerGroupAmountJson(SaleReportSearchParam param)
        {
            try
            {
                param.SaleYear = param.SaleYear.IsEmpty() ? DateTime.Now.Year : param.SaleYear;
                List<ProjectEntity> queryable = await _dbContext.Queryable<ProjectEntity>()
                                    .Includes(x => x.ProjectOperateCosts)
                                    .Where(x => x.FormType == ProjectFormEnum.CustomerSettlement.ToString() && x.Status == (int)ProjectStatusEnum.Closed)
                                    .WhereIF(!param.SaleYear.IsEmpty(), x => x.DepartureDate.Value.Year == param.SaleYear)//默认当年
                                    .ToListAsync();
                var groupbyResult = queryable.GroupBy(x => new
                {
                    Month = x.DepartureDate.Value.ToString("yyyy-MM")
                })
                .Select(x => new
                {
                    Month = x.Key.Month,
                    Amount = x.Sum(y => y.SaleRMBAmountAfterTax)//汇总销售金额
                }).ToList();

                List<SaleReportVo> monthDatas = new List<SaleReportVo>();
                SaleReportVo saleCommosionVo = new SaleReportVo();
                for (int i = 1; i <= 12; i++)
                {
                    var data = Math.Round((groupbyResult.FirstOrDefault(x => x.Month.ToDate().Month == i)?.Amount) ?? 0, 2, MidpointRounding.AwayFromZero);
                    switch (i)
                    {
                        case 1:
                            saleCommosionVo.January = data;
                            break;

                        case 2:
                            saleCommosionVo.February = data;
                            break;

                        case 3:
                            saleCommosionVo.March = data;
                            break;

                        case 4:
                            saleCommosionVo.April = data;
                            break;

                        case 5:
                            saleCommosionVo.May = data;
                            break;

                        case 6:
                            saleCommosionVo.June = data;
                            break;

                        case 7:
                            saleCommosionVo.July = data;
                            break;

                        case 8:
                            saleCommosionVo.August = data;
                            break;

                        case 9:
                            saleCommosionVo.September = data;
                            break;

                        case 10:
                            saleCommosionVo.October = data;
                            break;

                        case 11:
                            saleCommosionVo.November = data;
                            break;

                        case 12:
                            saleCommosionVo.December = data;
                            break;
                    }
                    saleCommosionVo.Total = saleCommosionVo.Total + data;
                }
                monthDatas.Add(saleCommosionVo);
                if (monthDatas.Count() == 0)
                {
                    return Content(DataResult<int>.Warn(0, "暂无数据导出").ToJson());
                }
                //导出列名
                string[] column = new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
                //文件名
                var fileName = "团队销售金额.xls";
                //表头
                var headerText = "团队销售金额";
                var file = ExcelHelper<SaleReportVo>.ExportToExcel(fileName, headerText, monthDatas, column);
                return Content(DataResult<string>.Success(file, "导出成功").ToJson());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 编辑销售操作率
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<ActionResult> SetOperateRateForm(int projectId)
        {
            ProjectEntity project = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(projectId);
            return Content(DataResult<ProjectEntity>.Success(project).ToJson());
        }

        /// <summary>
        /// 编辑销售操作率
        /// </summary>
        /// <param name="baseDto"></param>
        /// <returns></returns>

        [HttpPost]
        public async Task<ActionResult> SaveOperateRateForm(OperateRateDto operateRateDto)
        {
            try
            {
                ProjectEntity project = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(operateRateDto.ProjectId);
                project.OperateRate = operateRateDto.OperateRate;
                project.UpdatedOn = DateTime.Now;
                project.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                await _dbContext.Updateable<ProjectEntity>(project).UpdateColumns(x => new { x.OperateRate, x.UpdatedOn, x.UpdatedBy }).ExecuteCommandAsync();
                return Json(DataResult.Success());
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"{ex.Message}"));
            }
        }

        /// <summary>
        /// 成本支付完成
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> CompleteCostPay(int projectId)
        {
            try
            {
                ProjectEntity projectEntity = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(projectId);
                projectEntity.PayStatus = (int)ProjectCostPayEnum.Paid;
                projectEntity.UpdatedOn = DateTime.Now;
                projectEntity.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                await _dbContext.Updateable(projectEntity).UpdateColumns(x => new { x.PayStatus, x.UpdatedOn, x.UpdatedBy }).ExecuteCommandAsync();
                return Json(DataResult.Success("支付完成！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 付款申请列表
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public async Task<ActionResult> GetPayApplyPageListJson(BaseSearchParam param, Pagination pagination)
        {
            RefAsync<int> totalCount = 0;
            var datas = await _dbContext.Queryable<ProjectEntity>()
                                .Where(x => x.FormType == ProjectFormEnum.FinanceSettlement.ToString())//成本结算单
                                .Where(x=> x.PayStatus == (int)ProjectCostPayEnum.PayAudit || x.PayStatus == (int)ProjectCostPayEnum.PayAuditPass)//审核中和审核通过
                                .Where(x=>SqlFunc.SplitIn(x.PayAuditId, OperatorProvider.Provider.GetCurrent().Id.ToString()))//当前操作人
                                .WhereIF(!param.KeyWord.IsEmpty(), x => x.Code.Contains(param.KeyWord) || x.ContractCode.Contains(param.KeyWord) || x.Name.Contains(param.KeyWord) || x.CustomerName.Contains(param.KeyWord))
                                .OrderByDescending(x => x.PayApplyOn)
                                .ToPageListAsync(pagination.PageIndex, pagination.PageSize, totalCount);
            return Content(DataResult<List<ProjectEntity>>.PageResult(datas, totalCount).ToJson());
        }

        /// <summary>
        /// 审核成本支付申请(管理审核通过=>转到财务付款,通过PayAuditId识别)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> AuditPayApply(int projectId, string type)
        {
            try
            {
                ProjectEntity projectEntity = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(projectId);
                switch (type)
                {
                    case "pass":
                        projectEntity.PayStatus = (int)ProjectCostPayEnum.PayAuditPass;
                        //获取财务角色用户
                        var users = await _dbContext.Queryable<UserRole>().Includes(x => x.Role).Where(x => x.Role.Code == RoleTypeEnum.Fiance.ToString()).ToListAsync();
                        projectEntity.PayAuditId = string.Join(",", users.Select(x => x.UserId).ToArray()); ;//转给财务付款
                        break;
                    case "refuse":
                        projectEntity.PayAuditId = OperatorProvider.Provider.GetCurrent().Id.ToString();
                        projectEntity.PayStatus = (int)ProjectCostPayEnum.NotPay;
                        break;
                } 
                projectEntity.UpdatedOn = projectEntity.PayAuditOn = DateTime.Now;
                projectEntity.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                await _dbContext.Updateable(projectEntity).UpdateColumns(x => new { x.PayStatus,x.PayAuditId,x.PayAuditOn, x.UpdatedOn, x.UpdatedBy }).ExecuteCommandAsync();
                return Json(DataResult.Success("审核完成！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 财务付款完成
        /// </summary>
        /// <param name="projectId"></param> 
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> CompletePayApply(int projectId)
        {
            try
            {
                ProjectEntity projectEntity = await _dbContext.Queryable<ProjectEntity>().InSingleAsync(projectId);
                projectEntity.PayAuditId= OperatorProvider.Provider.GetCurrent().Id.ToString();
                projectEntity.PayStatus= (int)ProjectCostPayEnum.Paid;
                projectEntity.UpdatedOn = projectEntity.PayAuditOn = DateTime.Now;
                projectEntity.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                await _dbContext.Updateable(projectEntity).UpdateColumns(x => new { x.PayStatus, x.PayAuditId, x.PayAuditOn, x.UpdatedOn, x.UpdatedBy }).ExecuteCommandAsync();
                return Json(DataResult.Success("支付完成！"));
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"失败,失败原因:{ex.Message}"));
            }
        }
        
    }
}